home *** CD-ROM | disk | FTP | other *** search
- #include <Events.h>
- #include <Fonts.h>
- #include <math.h>
- #include <Memory.h>
- #include <OSUtils.h>
- #include <QuickDraw.h>
- #include <Sound.h>
- #include "::runtime:mlvalues.h"
- #include "::runtime:alloc.h"
- #include "::runtime:memory.h"
- #include "::runtime:fail.h"
- #include "::runtime:str.h"
- #include "ui.h"
-
- #define grafpk ((graphPeek) CAMLOffScreen)
- #define offset_x (grafpk->destRect.left - grafpk->viewRect.left)
- #define offset_y (grafpk->destRect.top - grafpk->viewRect.top)
- #define Short_val(x) ((short) Long_val(x))
- #define convert_y(y) (CAMLOffScreen->portRect.bottom - 1 - Short_val(y))
-
- #define Begin_offscreen \
- { GDHandle old_device; \
- if (color_qd){ \
- old_device = GetGDevice (); \
- SetGDevice (CAMLGDevice); \
- SetPort (CAMLOffScreen); \
- }
-
- #define End_offscreen \
- if (color_qd){ \
- SetGDevice (old_device); \
- } \
- }
-
- typedef struct graph {
- GrafPort offScreen;
- Rect destRect;
- Rect viewRect;
- Rect destRectZoom;
- } graphRecord, *graphPeek;
-
- extern WindowPtr CAMLGraph;
- extern WindowPtr CAMLOffScreen;
- extern GDHandle CAMLGDevice;
- extern int max_depth;
- extern char GraphKey;
-
- void copy_bits (const BitMap *, const BitMap *, const Rect *,
- const Rect *, short, RgnHandle);
- void copy_mask (const BitMap *, const BitMap *, const BitMap *,
- const Rect *, const Rect *, const Rect *);
- void LookGraphEvent (EventRecord *result, int move_ok, int null_ok);
- void LookEvent(unsigned long delay);
- Boolean OpenGraph(void);
- void DoClose(WindowPtr window);
- extern void enter_blocking_section (void);
- extern void leave_blocking_section (void);
-
- void graphic_fail(msg)
- char * msg;
- {
- raise_with_arg(GRAPHIC_FAILURE_EXN, copy_string(msg));
- }
-
- static void check_graph()
- {
- if (CAMLGraph == nil)
- graphic_fail("graphic window not opened");
- }
-
- value open_graph(str) /* ML */
- value str;
- {
- #pragma unused(str)
- if (CAMLGraph == nil) {
- if (!OpenGraph())
- graphic_fail("open_graph: cannot open graphic window");
- moveto(Val_long(0), Val_long(0));
- }
- return Atom(0);
- }
-
- value close_graph() /* ML */
- {
- check_graph();
- DoClose(CAMLGraph);
- return Atom(0);
- }
-
- value clear_graph() /* ML */
- {
- check_graph();
- SetPort(CAMLGraph);
- EraseRect(&grafpk->viewRect);
- Begin_offscreen
- EraseRect(&CAMLOffScreen->portRect);
- End_offscreen
- return Atom(0);
- }
-
- value size_x() /* ML */
- {
- Rect * r;
-
- check_graph();
- r = &CAMLOffScreen->portRect;
- return Val_long(r->right - r->left);
- }
-
- value size_y() /* ML */
- {
- Rect * r;
-
- check_graph();
- r = &CAMLOffScreen->portRect;
- return Val_long(r->bottom - r->top);
- }
-
- value set_color(color) /* ML */
- value color;
- {
- long col = Long_val (color);
-
- check_graph();
- if (color_qd){
- RGBColor qd_col;
-
- qd_col.red = (col >> 16) * 257;
- qd_col.green = ((col >> 8) & 0xff) * 257;
- qd_col.blue = (col & 0xff) * 257;
- SetPort (CAMLGraph);
- RGBForeColor (&qd_col);
- Begin_offscreen
- RGBForeColor (&qd_col);
- End_offscreen
- }else{
- SetPort(CAMLGraph);
- if (col == 0xffffff){
- PenPat (qd.white);
- TextMode (srcBic);
- }else{
- PenPat (qd.black);
- TextMode (srcOr);
- }
- SetPort(CAMLOffScreen);
- if (col == 0xffffff){
- PenPat (qd.white);
- TextMode (srcBic);
- }else{
- PenPat (qd.black);
- TextMode (srcOr);
- }
- }
- return Atom(0);
- }
-
- value plot(x, y) /* ML */
- value x, y;
- {
- short h, v;
- Point old_pen_size;
-
- check_graph();
- h = Short_val(x);
- v = convert_y(y);
- SetPort(CAMLOffScreen);
- old_pen_size = CAMLOffScreen->pnSize;
- PenSize (1, 1);
- MoveTo(h, v);
- LineTo(h, v);
- PenSize (old_pen_size.h, old_pen_size.v);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- h += offset_x;
- v += offset_y;
- PenSize (1, 1);
- MoveTo(h, v);
- LineTo(h, v);
- PenSize (old_pen_size.h, old_pen_size.v);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value point_color(x, y) /* ML */
- value x, y;
- {
- Point p;
-
- check_graph();
- SetPt(&p, Short_val(x), convert_y(y));
- if (!PtInRect(p, &CAMLOffScreen->portRect))
- graphic_fail("point_color: point out of graphic window");
- if (color_qd){
- RGBColor qd_col;
- Begin_offscreen
- GetCPixel (p.h, p.v, &qd_col);
- End_offscreen
- return Val_long ((qd_col.red / 256 << 16)
- + (qd_col.green / 256 << 8)
- + (qd_col.blue / 256));
- }else{
- SetPort(CAMLOffScreen);
- return GetPixel(p.h, p.v) ? Val_long(0) : Val_long(0xFFFFFF);
- }
- }
-
- value moveto(x, y) /* ML */
- value x, y;
- {
- check_graph();
- SetPort(CAMLOffScreen);
- MoveTo(Short_val(x), convert_y(y));
- return Atom(0);
- }
-
- value current_point() /* ML */
- {
- value res;
- Point p;
-
- check_graph();
- SetPort(CAMLOffScreen);
- GetPen(&p);
- res = alloc_tuple(2);
- Field(res, 0) = Val_long(p.h);
- Field(res, 1) = Val_long(convert_y(Val_long(p.v)));
- return res;
- }
-
- value lineto(x, y) /* ML */
- value x, y;
- {
- short h, v;
- Point p;
-
- check_graph();
- SetPort(CAMLOffScreen);
- GetPen(&p);
- h = Short_val(x);
- v = convert_y(y);
- LineTo(h, v);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- MoveTo(p.h + offset_x, p.v + offset_y);
- LineTo(h + offset_x, v + offset_y);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value draw_arc(argv, argn) /* ML */
- value * argv;
- int argn;
- {
- #pragma unused(argn)
- short h, v, r_x, r_y, start, arc;
- Rect r;
-
- check_graph();
- r_x = Short_val(argv[2]);
- r_y = Short_val(argv[3]);
- if ((r_x < 0) || (r_y < 0))
- graphic_fail("draw_arc: radius must be positives");
- h = Short_val(argv[0]);
- v = convert_y(argv[1]);
- SetRect(&r, h - r_x, v - r_y, h + r_x + 1, v + r_y + 1);
- SetPort(CAMLOffScreen);
- start = Short_val(argv[4]);
- arc = Short_val(argv[5]) - start;
- while (arc < 0)
- arc += 360;
- FrameArc(&r, 90 - start, -arc);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetRect(&r, offset_x, offset_y);
- FrameArc(&r, 90 - start, -arc);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value set_line_width(width) /* ML */
- value width;
- {
- short size;
-
- check_graph();
- size = Short_val(width);
- if (size < 0)
- graphic_fail("set_line_width: width must be positive");
- SetPort(CAMLOffScreen);
- PenSize(size, size);
- SetPort(CAMLGraph);
- PenSize(size, size);
- return Atom(0);
- }
-
- value draw_char(ch) /* ML */
- value ch;
- {
- Point p;
-
- check_graph();
- Begin_offscreen
- GetPen(&p);
- DrawChar((char) Long_val(ch));
- End_offscreen
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- MoveTo(p.h + offset_x, p.v + offset_y);
- DrawChar((char) Long_val(ch));
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value draw_string(str) /* ML */
- value str;
- {
- mlsize_t len;
- Point p;
-
- check_graph();
- if ((len = string_length(str)) > 32767)
- len = 32767;
- Begin_offscreen
- GetPen(&p);
- DrawText(Bp_val(str), 0, (unsigned short) len);
- End_offscreen
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- MoveTo(p.h + offset_x, p.v + offset_y);
- DrawText(Bp_val(str), 0, (short) len);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value set_font(str) /* ML */
- value str;
- {
- Str255 name;
- short i, len, fontnum;
-
- check_graph();
- len = string_length(str);
- for(i = 0; (i < len) && (i < 255); i++)
- name[i + 1] = Byte(str, i);
- name[0] = i;
- GetFNum(name,&fontnum);
- SetPort(CAMLOffScreen);
- TextFont(fontnum);
- SetPort(CAMLGraph);
- TextFont(fontnum);
- return Atom(0);
- }
-
- value set_text_size(size) /* ML */
- value size;
- {
- short s;
-
- check_graph();
- SetPort(CAMLOffScreen);
- s = Short_val(size);
- if (s < 0)
- graphic_fail("set_text_size: size must be positive");
- TextSize(s);
- SetPort(CAMLGraph);
- TextSize(s);
- return Atom(0);
- }
-
- value text_size(str) /* ML */
- value str;
- {
- value res;
- FontInfo info;
-
- check_graph();
- SetPort(CAMLOffScreen);
- GetFontInfo(&info);
- res = alloc_tuple(2);
- Field(res, 0) = Val_long(TextWidth(Bp_val(str), 0, string_length(str)));
- Field(res, 1) = Val_long(info.ascent + info.descent);
- return res;
- }
-
- value fill_rect(x, y, wdth, hgth) /* ML */
- value x, y, wdth, hgth;
- {
- short h, v, width, heigth;
- Rect r;
-
- check_graph();
- width = Short_val(wdth);
- heigth = Short_val(hgth);
- if ((width < 0) || (heigth < 0))
- graphic_fail("fill_rect: width and heigth must be positives");
- h = Short_val(x);
- v = convert_y(y) + 1;
- SetRect(&r, h, v - heigth, h + width, v);
- SetPort(CAMLOffScreen);
- PaintRect(&r);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetRect(&r, offset_x, offset_y);
- PaintRect(&r);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value fill_arc(argv, argn) /* ML */
- value * argv;
- int argn;
- {
- #pragma unused(argn)
- short h, v, r_x, r_y, start, arc;
- Rect r;
-
- check_graph();
- r_x = Short_val(argv[2]);
- r_y = Short_val(argv[3]);
- if ((r_x < 0) || (r_y < 0))
- graphic_fail("draw_arc: radius must be positives");
- h = Short_val(argv[0]);
- v = convert_y(argv[1]);
- SetRect(&r, h - r_x, v - r_y, h + r_x + 1, v + r_y + 1);
- start = Short_val(argv[4]);
- arc = Short_val(argv[5]) - start;
- while (arc < 0)
- arc += 360;
- SetPort(CAMLOffScreen);
- PaintArc(&r, 90 - start, -arc);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetRect(&r, offset_x, offset_y);
- PaintArc(&r, 90 - start, -arc);
- ClipRect(&CAMLGraph->portRect);
- return Atom(0);
- }
-
- value fill_poly(vect) /* ML */
- value vect;
- {
- int n_points, i;
- PolyHandle poly;
-
- check_graph();
- n_points = Wosize_val(vect);
- if (n_points < 3)
- graphic_fail("fill_poly: not enough points");
- SetPort(CAMLOffScreen);
- poly = OpenPoly();
- MoveTo(Short_val(Field(Field(vect, 0), 0)), convert_y(Field(Field(vect, 0), 1)));
- for(i = 1; i < n_points; i++)
- LineTo(Short_val(Field(Field(vect, i), 0)), convert_y(Field(Field(vect, i), 1)));
- LineTo(Short_val(Field(Field(vect, 0), 0)), convert_y(Field(Field(vect, 0), 1)));
- ClosePoly();
- PaintPoly(poly);
- SetPort(CAMLGraph);
- ClipRect(&grafpk->viewRect);
- OffsetPoly(poly, offset_x, offset_y);
- PaintPoly(poly);
- ClipRect(&CAMLGraph->portRect);
- KillPoly(poly);
- return Atom(0);
- }
-
- struct image {
- value w;
- value h;
- value data;
- value mask;
- };
-
- #define Width(i) (((struct image *) i)->w)
- #define Height(i) (((struct image *) i)->h)
- #define Data(i) (((struct image *) i)->data)
- #define Mask(i) (((struct image *) i)->mask)
-
- static value new_bits(width, height, depth)
- int width, height;
- {
- int rowbytes, nbytes, nwords;
- value res;
-
- rowbytes = (depth * width + 31) / 32 * 4;
- nbytes = rowbytes * height;
- nwords = (nbytes + 3) / 4;
- if (nwords == 0) return Atom (Abstract_tag);
- if (nwords <= Max_young_wosize) {
- res = alloc(nwords, Abstract_tag);
- }else{
- res = alloc_shr(nwords, Abstract_tag);
- }
- return res;
- }
-
- static BitMap **image_to_bitmap (image, w, h, is_mask)
- value image;
- {
- if (color_qd && !is_mask){
- GDHandle old_device;
- PixMapHandle result;
-
- old_device = GetGDevice ();
- SetGDevice (CAMLGDevice);
- result = NewPixMap ();
- DisposHandle ((Handle) (*result)->pmTable);
- (*result)->pmTable = (*((CGrafPtr) CAMLOffScreen)->portPixMap)->pmTable;
- (*result)->baseAddr = (Ptr) image;
- (*result)->rowBytes = (max_depth * w + 31) / 32 * 4 + 0x8000;
- SetRect (&(*result)->bounds, 0, 0, w, h);
- SetGDevice (old_device);
- return (BitMap **) result;
- }else{
- BitMap **result = (BitMap **) NewHandle (sizeof (BitMap));
-
- (*result)->baseAddr = (Ptr) image;
- (*result)->rowBytes = (w + 31) / 32 * 4;
- SetRect(&(*result)->bounds, 0, 0, w, h);
- return result;
- }
- }
-
- value make_image (value mat) /* ML */
- {
- int height, width, i, j;
- int has_transp;
- GrafPtr old_port;
- value res;
- Push_roots(roots, 3)
- #define bdata (roots[0])
- #define bmask (roots[1])
- #define matrix (roots[2])
-
- check_graph ();
- matrix = mat;
- GetPort (&old_port);
- height = Wosize_val(matrix);
- if (height == 0) {
- width = 0;
- } else {
- width = Wosize_val(Field(matrix, 0));
- for (i = 1; i < height; i++) {
- if (width != Wosize_val(Field(matrix, i)))
- graphic_fail("make_image: non-rectangular matrix");
- }
- }
- bdata = new_bits (width, height, max_depth);
- has_transp = 0;
- if (color_qd){
- CGrafPort port;
- RGBColor qd_col;
- long col;
-
- OpenCPort (&port);
- DisposHandle ((Handle) port.portPixMap);
- port.portPixMap = (PixMapHandle) image_to_bitmap (bdata, width, height, 0);
- port.portRect = (*port.portPixMap)->bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- col = Long_val (Field (Field (matrix, i), j));
- if (col == -1){
- has_transp = 1;
- }else{
- qd_col.red = (col >> 16) * 256;
- qd_col.green = ((col >> 8) & 0xff) * 256;
- qd_col.blue = (col & 0xff) * 256;
- SetCPixel (j, i, &qd_col);
- }
- }
- }
- SetPort (old_port);
- CloseCPort (&port);
- }else{
- GrafPort port;
- BitMap **h;
-
- OpenPort (&port);
- h = image_to_bitmap (bdata, width, height, 0);
- port.portBits = **h;
- DisposHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- EraseRect (&port.portBits.bounds);
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- switch (Long_val (Field (Field (matrix, i), j))){
- case -1: has_transp = 1; break;
- case 0xFFFFFF: break;
- default: MoveTo (j, i); Line (0, 0); break;
- }
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }
- if (has_transp) {
- GrafPort port;
- BitMap **h;
-
- bmask = new_bits (width, height, 1);
- OpenPort (&port);
- h = image_to_bitmap (bmask, width, height, 1);
- port.portBits = **h;
- DisposHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- EraseRect (&port.portBits.bounds);
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- if (Long_val (Field (Field (matrix, i), j)) != -1){
- MoveTo (j, i); Line (0, 0);
- }
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }else{
- bmask = Val_long (0);
- }
- res = alloc_tuple (4);
- Width (res) = Val_int (width);
- Height (res) = Val_int (height);
- Data (res) = bdata;
- Mask (res) = bmask;
- Pop_roots ();
- return res;
- #undef matrix
- #undef bdata
- #undef bmask
- }
-
- static value alloc_int_vect(size)
- mlsize_t size;
- {
- value res;
- mlsize_t i;
-
- if (size == 0) return Atom(0);
- if (size <= Max_young_wosize) {
- res = alloc(size, 0);
- } else {
- res = alloc_shr(size, 0);
- }
- for (i = 0; i < size; i++) {
- Field(res, i) = Val_long(0);
- }
- return res;
- }
-
- value dump_image(value image) /* ML */
- {
- int height, width, i, j;
- GrafPtr old_port;
- Push_roots(roots, 2);
- #define matrix (roots[0])
- #define im (roots [1])
-
- check_graph ();
- im = image;
- GetPort (&old_port);
- height = Int_val (Height (im));
- width = Int_val (Width (im));
- matrix = alloc_int_vect (height);
- for (i = 0; i < height; i++) {
- modify (&Field (matrix, i), alloc_int_vect (width));
- }
-
- if (color_qd){
- CGrafPort port;
- RGBColor qd_col;
-
- OpenCPort (&port);
- DisposHandle ((Handle) port.portPixMap);
- port.portPixMap
- = (PixMapHandle) image_to_bitmap (Data (im), width, height, 0);
- port.portRect = (*port.portPixMap)->bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- GetCPixel (j, i, &qd_col);
- Field (Field (matrix, i), j) = Val_long ((qd_col.red / 256 << 16)
- + (qd_col.green / 256 << 8)
- + qd_col.blue / 256);
- }
- }
- SetPort (old_port);
- CloseCPort (&port);
- }else{
- GrafPort port;
- BitMap **h;
-
- OpenPort (&port);
- h = image_to_bitmap (Data (im), width, height, 0);
- port.portBits = **h;
- DisposHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- Field (Field (matrix, i), j)
- = Val_long (GetPixel (j, i) ? 0 : 0xFFFFFF);
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }
-
- if (Mask(im) != Val_long(0)) {
- GrafPort port;
- BitMap **h;
-
- OpenPort (&port);
- h = image_to_bitmap (Mask (im), width, height, 1);
- port.portBits = **h;
- DisposHandle ((Handle) h);
- port.portRect = port.portBits.bounds;
- for (i = 0; i< height; i++){
- for (j = 0; j < width; j++){
- if (! GetPixel (j, i)) Field (Field (matrix, i), j) = -1;
- }
- }
- SetPort (old_port);
- ClosePort (&port);
- }
- Pop_roots();
- return matrix;
- #undef matrix
- #undef im
- }
-
- value draw_image(image, x, y) /* ML */
- value image, x, y;
- {
- short rx, ry;
- int w, h;
- BitMap **src_bitmap, **mask_bitmap;
- Rect dst_rect, src_rect;
-
- check_graph();
- w = Int_val (Width (image));
- h = Int_val (Height (image));
- rx = Long_val(x);
- ry = convert_y(y) - h + 1;
- SetRect (&dst_rect, rx, ry, rx + w, ry + h);
- SetRect (&src_rect, 0, 0, w, h);
- Begin_offscreen
- if (Mask (image) != Val_long(0)) {
- src_bitmap = image_to_bitmap (Data(image), w, h, 0);
- mask_bitmap = image_to_bitmap (Mask(image), w, h, 1);
- copy_mask (*src_bitmap, *mask_bitmap, &CAMLOffScreen->portBits,
- &src_rect, &src_rect, &dst_rect);
- DisposHandle ((Handle) src_bitmap);
- DisposHandle ((Handle) mask_bitmap);
- }else{
- src_bitmap = image_to_bitmap (Data(image), w, h, 0);
- copy_bits (*src_bitmap, &CAMLOffScreen->portBits,
- &src_rect, &dst_rect, srcCopy, nil);
- DisposHandle ((Handle) src_bitmap);
- }
- End_offscreen
- OffsetRect(&dst_rect, offset_x, offset_y);
- SectRect(&dst_rect, &grafpk->viewRect, &dst_rect);
- src_rect = dst_rect;
- OffsetRect(&src_rect, -offset_x, -offset_y);
- SetPort (CAMLGraph);
- copy_bits (&CAMLOffScreen->portBits, &CAMLGraph->portBits,
- &src_rect, &dst_rect, srcCopy, nil);
- return Atom(0);
- }
-
- value create_image (value w, value h) /* ML */
- {
- value res;
- Push_roots (roots, 1);
- #define bdata (roots[0])
-
- check_graph ();
- if (Int_val (w) < 0 || Int_val (h) < 0)
- graphic_fail("get_image: width and height must be positive");
- bdata = new_bits (Int_val (w), Int_val (h), max_depth);
- res = alloc_tuple (4);
- Width (res) = w;
- Height (res) = h;
- Data (res) = bdata;
- Mask (res) = Val_long (0);
- Pop_roots ();
- return res;
- #undef bdata
- }
-
- value blit_image (value i, value x, value y) /* ML */
- {
- short rx, ry, width, height;
- BitMap **dst_bitmap;
- Rect src_rect;
-
- check_graph();
- width = Short_val (Width (i));
- height = Short_val (Height (i));
- dst_bitmap = image_to_bitmap (Data (i), width, height, 0);
- rx = Short_val(x);
- ry = convert_y(y) + 1;
- SetRect (&src_rect, rx, ry - height, rx + width, ry);
- Begin_offscreen
- copy_bits (&CAMLOffScreen->portBits, *dst_bitmap,
- &src_rect, &(*dst_bitmap)->bounds, srcCopy, nil);
- End_offscreen
- return Atom (0);
- }
-
- value wait_event (value l) /* ML */
- {
- int b_down = 0;
- int b_up = 0;
- int key_press = 0;
- int motion = 0;
- int poll = 0;
- EventRecord event;
- value result;
-
- check_graph ();
- enter_blocking_section ();
- while (l != Atom (0)){
- switch (Tag_val (Field (l, 0))){
- case 0: b_down = 1; break;
- case 1: b_up = 1; break;
- case 2: key_press = 1; break;
- case 3: motion = 1; break;
- case 4: poll = 1; break;
- }
- l = Field (l, 1);
- }
- while (1){
- LookGraphEvent (&event, motion, poll);
- if (poll || motion
- || b_down && event.what == mouseDown
- || b_up && event.what == mouseUp
- || key_press && event.what == keyDown)
- break;
- }
- result = alloc_tuple (5);
- SetPort (CAMLGraph);
- GlobalToLocal (&event.where);
- Field (result, 0) = Val_int (event.where.h - offset_x);
- Field (result, 1) = Val_int (CAMLOffScreen->portRect.bottom - 1
- - (event.where.v - offset_y));
- Field (result, 2) = Atom (!(event.modifiers & btnState));
- if (event.what == keyDown){
- Field (result, 3) = Atom (1);
- Field (result, 4) = Val_int (event.message & charCodeMask);
- }else{
- Field (result, 3) = Atom (0);
- Field (result, 4) = Val_int (0);
- }
- leave_blocking_section ();
- return result;
- }
-
- value sound(freq, delay) /* ML */
- value freq, delay;
- {
- long f = Long_val (freq);
- long d = Long_val (delay);
- int note;
- SndCommand cmd;
- SndChannelPtr chan = NULL;
-
- enter_blocking_section();
- note = 69 + (log((double) f / 440.0) / log(twelfthRootTwo) + 0.5);
- if (note < 1) note = 1;
- if (note > 127) note = 127;
- cmd.cmd = freqDurationCmd;
- cmd.param1 = d * 2;
- cmd.param2 = 0xFF000000 + note;
- if (SndNewChannel (&chan, squareWaveSynth, 0, NULL) != noErr){
- SysBeep (1);
- }else{
- if (SndDoCommand (chan, &cmd, 0) != noErr) SysBeep(1);
- SndDisposeChannel (chan, 0);
- }
- leave_blocking_section();
- return Atom(0);
- }
-